Skip to content

Conversation

@subha-sa
Copy link
Contributor

@subha-sa subha-sa commented Oct 3, 2025

Description

The PR, makes scope property fully qualified resource Id.

Checklist

Microsoft Reviewers: Open in CodeFlow

@github-actions
Copy link
Contributor

github-actions bot commented Oct 3, 2025

Test this change out locally with the following install scripts (Action run 19252787923)

VSCode
  • Mac/Linux
    bash <(curl -Ls https://aka.ms/bicep/nightly-vsix.sh) --run-id 19252787923
  • Windows
    iex "& { $(irm https://aka.ms/bicep/nightly-vsix.ps1) } -RunId 19252787923"
Azure CLI
  • Mac/Linux
    bash <(curl -Ls https://aka.ms/bicep/nightly-cli.sh) --run-id 19252787923
  • Windows
    iex "& { $(irm https://aka.ms/bicep/nightly-cli.ps1) } -RunId 19252787923"

@github-actions
Copy link
Contributor

github-actions bot commented Oct 3, 2025

Dotnet Test Results

    96 files   -     48      96 suites   - 48   42m 8s ⏱️ - 28m 23s
12 411 tests  -      8  12 411 ✅  -      8  0 💤 ±0  0 ❌ ±0 
28 567 runs   - 14 262  28 567 ✅  - 14 262  0 💤 ±0  0 ❌ ±0 

Results for commit a22ca09. ± Comparison against base commit 066c054.

This pull request removes 1924 and adds 661 tests. Note that renamed tests count towards both.

		nestedProp1: 1
		nestedProp2: 2
		prop1: true
		prop2: false
	1
	2
	\$'")
	prop1: true
	prop2: false
…
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000
�ӱ
�0\u0010\u0006��>E�\u0003����Z��Ep�\u0001b{b�Vi+\u0014�w�\u001dĥťZ�|c� �\u000b�\u00087�Y�K����V���
ZV�����$>\u0001\u00034F1ƛ�'�q�jW��|�\u001f�"��,��D\u0013��1�B��@ų��\u000c�d�/�>,�"�F\u001c�sѵ�C�S?�\u001b���ϭ�]�a��4���\u0014*\u0006֘���%����\u001b\u000f�\u00055\u0017JjJה�\u000c\u0016|�N\u0015ݧ���<���\u0007�\u0005�!\u0000\u000c\u0000\u0000,"Value cannot be null. (Parameter 'source')")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000
��A\u000b�0\u0014\u0007��\u0014�\u0007����4�\u0010t�\u0008\u000b��1r��\u0016j �囇�tQ\u000b���`o\u001b�ao���V�.+L��\u001eFC#��s�E9 
/\u0004\u0011\u0010�!�4�O��^ժ4�L��\u000fb���,�\u0011\u0005\u0011�\u000c!����\u0007,��ک�FC��s�\u0015�n�\u0016m{����cZ=��7�\u0015}�?a\u001cQA�\u00000\u0006\u000c\u0011)�o�?I&�<�\u000f7N\u000e�M�<���ĝ;�\u0007��L�eY�����IW\u0000\u000c\u0000\u0000,"'7' is an invalid end of a number. Expected a delimiter. Path: $.INVALID_JSON | LineNumber: 0 | BytePositionInLine: 20.")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000
��K\u000e�0\u0010\u0006�=\u0005'(3uځ\u0005{�^�Q\u0012\u001f�\u0018\u001e��xw���\u0005�
�����L:�������\u001e\udb69\udd88�b)�\u0006�!\u001a=\u001f�F��\u0002\u0002X�\u0016"�g�dD[7��,q�\u000fRId�s�g�:e�rb$j�D���\u000e�5�n�9e����s�R�nh(�\u001a�~h0������O�\u0007P\u0002500+���\u001f���H&�<����\u0013\u0004A\u0010\u0004kx\u0002��\u0006\u000c\u0000\u000c\u0000\u0000,"The path: index.json was not found in artifact contents")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0003�Խ
�0\u0010\u0007��>E�\u0003��6��B\u0007���TAp��\u0005\u0015���P��M\u0007qiq�V0�1���\u0010.�_�j��]�\u0017"D\u0019��}\u001aXZ���T�$=\u0001\u0003B\u000c\u0018���'ip+J��Q�����!7��Œ0"\u001diT\u0002($�j`k۶���Ք��p�e�8\u0016�s\u001d?��������~���n�!PL"\u0010\u0010\u0005�5\u0003�hӼ������{I�\u001eϓ�f�Z�ވ�\u001f��\u001c�q��{\u0000`*��\u0000\u000c\u0000\u0000,"'7' is an invalid end of a number. Expected a delimiter. Path: $.INVALID_JSON | LineNumber: 0 | BytePositionInLine: 20.")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0003���
�0\u000c\u0006��}��\u0007��ִ���\u0017��\u000fP��\u00137�6a ��� ^6��\u0013�wl\u0002I	���]�$�Q݈\u0008e4\u0017�ݠ��\u001a|���0i\u001e��A\u000c\u0019���7\u0019pnZW��|c�\u000f
c�ڼ�D\u001a�F[�J@lc\u001d�Y_K�j��ʵ�$/3�ġ9���b�}�oz#���܌W��H1�`��\u0010�f�\u0011���W2�����`SRWQ�R��bKu��;wl�:�n��y���\u0000��5�\u0000\u000c\u0000\u0000,"Value cannot be null. (Parameter 'source')")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0003���
�0\u000c\u0007��\u0014}��h�̃�\u001d�
e\u0013��u���ػ�\u001e\u0006;(�8\u001d��cCHJ��ho�]n�yU��0���\u001bxF���\u0001\u0012
�\u0017\u0010��I\u0008�ϾɈ�nl�WYb�\u000f���6�"ϐ)e�\u001a�
��\u0016%\u001b_;L�P�ls�Zwue�ԥ.��PL5���`����5�S�\u0001b�\u0004\u000c�1\u0018����Q.��?�����\u0006A\u0010\u0004�\u001a��P�\u0000\u000c\u0000\u0000,"The path: index.json was not found in artifact contents")
Bicep.Core.IntegrationTests.DirectResourceCollectionTests ‑ DirectResourceCollectionAccess_NotAllowedWithinLoops ("output loopOutput array = [for i in range(0, 2): {
  prop: map(containerWorkers, (w) => w.properties.ipAddress.ip)
}]")
Bicep.Core.IntegrationTests.DirectResourceCollectionTests ‑ DirectResourceCollectionAccess_NotAllowedWithinLoops ("resource propertyLoop 'Microsoft.ContainerInstance/containerGroups@2022-09-01' = {
  name: 'gh9440-loop'
  location: 'westus'
  properties: {
    containers: [for i in range(0, 2): {
      name: 'gh9440-w1c-${i}'
      properties: {
        command: [
          'echo "${join(map(containerWorkers, (w) => w.properties.ipAddress.ip), ',')}"'
        ]
      }
    }]
  }
}")
Bicep.Core.IntegrationTests.DirectResourceCollectionTests ‑ DirectResourceCollectionAccess_NotAllowedWithinLoops ("var loopVar = [for i in range(0, 2): {
  prop: map(containerWorkers, (w) => w.properties.ipAddress.ip)
}]")
Bicep.Core.IntegrationTests.Emit.ParamsFileWriterTests ‑ Params_file_with_no_errors_should_compile_correctly ("
using 'main.bicep'

// involves all syntax
param myParam = {
  arr: [
    {
      a : 'b'
    }
    {
      c : true
    }
  ]
  name: 'complex object!'
  priority: 3
  val: null
  obj: {
      a: 'b'
      c: [
          'd'
           1
      ]
  }
}","
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "myParam": {
      "value": {
        "arr" : [
          {
            "a" : "b"
          },
          {
            "c" : true
          }
        ],
        "name" : "complex object!",
        "priority" : 3,
        "val" : null,
        "obj" : {
          "a" : "b",
          "c" : [
            "d",
            1
          ]
        }
      }
    }
  }
}","
param myParam object
")
…

♻️ This comment has been updated with latest results.

Comment on lines 102 to 110
public void EmitFullyQualifiedResourceId(DeclaredResourceMetadata resource, IndexReplacementContext? indexContext)
{
var converterForContext = converter.GetConverter(indexContext);

var fullyQualifiedResourceId = converterForContext.GetFullyQualifiedResourceId(resource);
var serialized = ExpressionSerializer.SerializeExpression(fullyQualifiedResourceId);

writer.WriteValue(serialized);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm mistaken, the implementation looks identical to the existing function EmitResourceIdReference - can we commonize rather than creating a new one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, for pointing this out. I have renamed the existing one, just to be more explicit.

Copy link
Member

@majastrz majastrz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Copy link
Member

@anthony-c-martin anthony-c-martin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

"type": "Microsoft.Authorization/locks",
"apiVersion": "2016-09-01",
"scope": "[extensionResourceId(format('Microsoft.Storage/storageAccounts/{0}', format('{0}single-resource-name', parameters('name'))), 'Microsoft.Authorization/locks', 'single-resource-lock')]",
"scope": "[extensionResourceId(resourceId('Microsoft.Storage/storageAccounts', format('{0}single-resource-name', parameters('name'))), 'Microsoft.Authorization/locks', 'single-resource-lock')]",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change appears to be fixing a bug in that extensionResourceId assumes the first parameter is a fully qualified ID. I tried deploying a template with the output [extensionResourceId('Microsoft.Authorization/roleAssignments/foo', 'RP.Namespace/type', 'bar')] at a few scopes, and it always evaluates to /Microsoft.Authorization/roleAssignments/foo/providers/RP.Namespace/type/bar. So this is not strictly a no-op but is a desired change. We must not have caught this before because extension resources on extension resources aren't very common outside of test scenarios.

@subha-sa subha-sa merged commit c1d5325 into main Nov 11, 2025
42 of 43 checks passed
@subha-sa subha-sa deleted the bicepUpdateScope branch November 11, 2025 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants